package cn.wgx.common.security.client.filter;

import cn.wgx.common.security.client.config.entity.LoginAppUser;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;

/**
 *  客户端验证url权限
 */
public class Oauth2ClientPermissionFilter extends OncePerRequestFilter {

    //需要过滤权限的url, /api/
    private UrlPermissionRequestMatcher urlPermissionRequestMatcher = new UrlPermissionRequestMatcher();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //获取认证对象
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if(authentication instanceof OAuth2Authentication){
            //todo 验证URL权限
            Object principal = authentication.getPrincipal();
            if(principal instanceof LoginAppUser){
                LoginAppUser loginAppUser = (LoginAppUser)principal;
                if(!"admin".equals(loginAppUser.getUsername())){
                    //检测请求地址是否需要过滤权限
                    if(!urlPermissionRequestMatcher.matches(request)) {
                        filterChain.doFilter(request, response);
                        return;
                        //throw new ServletException("未登录,或超时,请重新登录");
                    }
                    //获取用户已有API权限列表
                    Set<String> permissions = loginAppUser.getPermissions();
                    boolean access = false;

                    //遍历用户API权限是否包含此次请求地址
                    String requestURI = request.getRequestURI();
                    String contextPath = request.getContextPath();
                    if(!contextPath.equals("")){
                        requestURI = requestURI.replaceFirst(contextPath, "");
                    }
                    for(String per: permissions){
                        if(requestURI.startsWith(per)){
                            access = true;
                            break;
                        }
                    }

                    if(!access){
                        throw new AccessDeniedException("无权限访问此接口.");
                    }
                }
            }
//            else{
//                throw new AccessDeniedException("未登录,或超时,请重新登录");
//            }
        }

        filterChain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }

    protected static class UrlPermissionRequestMatcher implements RequestMatcher {

        private String path = "/api/";

        public UrlPermissionRequestMatcher() {        }

        @Override
        public boolean matches(HttpServletRequest request) {
            String uri = request.getRequestURI();

            String contextPath = request.getContextPath();

            if ("".equals(contextPath)) {
                return uri.startsWith(path);
            }

            return uri.startsWith(contextPath + path);
        }

    }



}
